﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace MyFloridaHouse.libSvOpenDistricts.Census
{
    // Extends CensusGeometry Class to give it ability to dump a condensed list
    public static class CensusGeometryCondensed
    {
        // dump an entire condensed plan as a string
        public static string ToCondensed(this CensusGeometry censusGeometry, int iMaxDistricts)
        {
            List<string> _condensedPlan = InitializePlanCondensed(iMaxDistricts, censusGeometry.nodeList);

            StringBuilder condensedPlanStringBuilder = new StringBuilder();
            foreach (var districtString in _condensedPlan)
            {
                condensedPlanStringBuilder.Append(districtString + Environment.NewLine);
            }

            return condensedPlanStringBuilder.ToString();
        }

        // dump an entire condensed plan as a list of strings
        public static List<string> ToCondensedList(int iMaxDistricts)
        {
            List<string> _condensedPlan = InitializePlanCondensed(iMaxDistricts, CensusGeometry.censusGeometryInstance.nodeList);
            return _condensedPlan;
        }


        private static List<string> InitializePlanCondensed(int iMaxDistricts, List<CensusGeometryNode> censusGeometryNodeList)
        {
            List<string> _condensedPlan = new List<string>();

            // first determine the max district that resides in the districtPlan
            // this may be less than the total number of districts in a plan since
            // some districts may have no geographies assigned to them.
            int maxDistrictID = (from uog in censusGeometryNodeList select uog.districtID).Max();

            // Ensure that each possible district has an empty list of uogids
            maxDistrictID = Math.Max(maxDistrictID, iMaxDistricts);
            List<List<int>> listOfDistrictUogIDst = new List<List<int>>();
            for (int districtID = 0; districtID <= maxDistrictID; districtID++)
            {
                listOfDistrictUogIDst.Add(new List<int>());
            }

            // group each node by its district
            int parentNodeIndex = 0;
            GetDistrictNodes(ref listOfDistrictUogIDst, parentNodeIndex, censusGeometryNodeList);


            // Turn the list of intLists into a list of comma separated uogIDs
            _condensedPlan = new List<string>();
            for (int districtID = 0; districtID <= maxDistrictID; districtID++)
            {
                _condensedPlan.Add(String.Join(",",listOfDistrictUogIDst[districtID]));
            }
            
            return _condensedPlan;

        }

        private static void GetDistrictNodes(ref List<List<int>> listOfDistrictUogIDst, int parentNodeIndex, List<CensusGeometryNode> censusGeometryNodeList)
        {
            CensusGeometryNode parentNode = censusGeometryNodeList[parentNodeIndex];
            foreach (var node in censusGeometryNodeList[parentNodeIndex].childNodeList)
            {
                int districtID = node.districtID;
                if ((districtID >= 0))
                {
                    // add this geometry item to the district
                    listOfDistrictUogIDst[districtID].Add(node.uogID);
                }
                else
                {
                    GetDistrictNodes(ref listOfDistrictUogIDst, node.uogID, censusGeometryNodeList);
                }
            }
        }



    }
}
